<template>
  <el-button-group>
    <el-popover
      v-if="showPagination"
      :popper-style="{ padding: 0 }"
      placement="bottom-end"
      :width="160"
      trigger="click"
    >
      <template #reference>
        <el-button class="elbtn" :size="size">
          <img
            :class="'view_icon_' + size"
            referrerpolicy="no-referrer"
            src="@/assets/image/Export.png"
          />
          <span v-if="exportTitle">{{ exportTitle }}</span>
        </el-button>
      </template>
      <template #default>
        <div class="export-btn">
          <el-button link @click="handleExport('page')">Export Current Page</el-button>
          <el-button link @click="handleExport('all')">Export All</el-button>
        </div>
      </template>
    </el-popover>
    <el-button v-if="!showPagination" class="elbtn" :size="size" @click="handleExport('all')">
      <img
        :class="'view_icon_' + size"
        referrerpolicy="no-referrer"
        src="@/assets/image/Export.png"
      />
      <span v-if="exportTitle">{{ exportTitle }}</span>
    </el-button>
    <el-popover
      v-if="showChangeHeader"
      :popper-style="{ padding: 0 }"
      placement="bottom-end"
      :width="240"
      trigger="click"
    >
      <template #reference>
        <el-button class="elbtn" :size="size">
          <img
            :class="'view_icon_' + size"
            referrerpolicy="no-referrer"
            src="@/assets/image/TableSet.png"
          />
        </el-button>
      </template>
      <template #default>
        <div class="searchInput">
          <el-input
            v-model="searchVal"
            placeholder="Search"
            class="input-with-select"
            clearable
            :size="size"
            @input="treeRef.filter($event)"
          >
            <template #append>
              <el-button :size="size" :icon="Search" />
            </template>
          </el-input>
        </div>
        <div class="columFilter">
          <el-checkbox
            style="margin-left: 26px"
            :indeterminate="isIndeterminate"
            v-model="checkAll"
            v-show="!searchVal"
            :disabled="disabled"
            @change="handleCheckAllChange"
          >
            All
          </el-checkbox>
          <el-tree
            ref="treeRef"
            :data="filterList"
            show-checkbox
            default-expand-all
            node-key="id"
            :props="defaultProps"
            @check="handleCheck"
            :filter-node-method="handleTreeFilter"
          />
        </div>
      </template>
    </el-popover>
  </el-button-group>
</template>

<script setup>
import { Search } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { flatten } from '@/utils';
import { apiMethods } from '@/utils/http.js';

const props = defineProps({
  /**
   * 表格列表配置项集合
   */
  tableList: {
    type: Array,
    default: () => [],
  },
  /**
   * 导出信息，包括导出url地址，导出的传值参数
   */
  exportInfo: {
    type: Object,
    default: () => ({}),
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  size: {
    type: String,
    default: 'small',
  },
  showChangeHeader: {
    type: Boolean,
    default: true,
  },
  exportTitle: {
    type: String,
    default: '',
  },
  showPagination: {
    type: Boolean,
  },
});

const defaultProps = {
  children: 'children',
  label: 'label',
  disabled: 'disabled',
};

const emits = defineEmits(['columnChange']);

const originList = props.tableList
  .filter(i => !(i?.type || i?.label === 'Action'))
  .map(i => {
    let k = { ...i };
    if (k.children) {
      k.children = setChildId(k.children, k);
    }
    return { ...k, id: k.labelDiff || k.label, disabled: props.disabled };
  });

const treeRef = $ref();

onMounted(() => {
  filterList = [...originList];
  checkedValue = flattenArr;
  nextTick(() => {
    if (treeRef) treeRef.setCheckedNodes(checkedValue);
  });
});

const checkAll = computed(() => {
  return checkedValue.length === flattenArr.length;
});

const isIndeterminate = computed(() => {
  return checkedValue.length > 0 && checkedValue.length < flattenArr.length;
});

let flattenArr = $ref(flatten(originList));
let searchVal = $ref('');
let checkedValue = $ref([]);
let filterList = $ref([]);

function handleCheck(row, { checkedKeys, checkedNodes, halfCheckedKeys, halfCheckedNodes }) {
  checkedValue = checkedNodes;
  emits('columnChange', checkedValue);
}

function handleTreeFilter(value, data) {
  if (!value) return true;
  return data.label.toLowerCase().includes(value.toLowerCase());
}

function handleCheckAllChange(val) {
  checkedValue = val ? flattenArr : [];
  treeRef.setCheckedNodes(checkedValue);
  emits('columnChange', checkedValue);
}

function setChildId(arr, fa) {
  return arr.map(i => {
    if (i.children) {
      setChildId(i.children, i);
    }
    return {
      disabled: props.disabled,
      ...i,
      id: `${fa.labelDiff || fa.label}-${i.labelDiff || i.label}`,
    };
  });
}

async function handleExport(type) {
  let search = JSON.parse(JSON.stringify(props.exportInfo.search));
  search.downloadKeys = checkedValue.map(i => i.id).join(',');
  search.fileName = props.exportInfo.fileName || 'Export';
  if (type === 'all') {
    search.downloadIds = 'All';
    delete search.pageSize;
    delete search.pageNum;
  }
  apiMethods['post_export'](props.exportInfo.api, search)
    .then(res => {
      ElMessage.success('Download Success');
    })
    .catch(err => {
      ElMessage.error('Download Failed');
    });
}
</script>

<style scoped lang="scss">
.elbtn {
  padding: 8px;
}
.view_icon_small {
  width: 20px;
  height: 20px;
}
.export-btn {
  margin: 5px 10px;
  text-align: left;
  button {
    display: block;
    height: 32px;
    margin-left: 0;
    width: 100%;
    text-align: left;
    color: rgb(48, 49, 51);
  }
}
.tableSetPop {
  padding: 0;
}
.searchInput {
  padding: 10px;
  text-align: center;
  border-bottom: 1px solid #eaeaea;
  .input-with-select {
    width: 200px;
  }
}
.columFilter {
  padding: 10px 20px;
  max-height: 200px;
  overflow-y: auto;
  .columItem {
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
</style>
